<?php
// +----------------------------------------------------------------------
// | Bwsaas
// +----------------------------------------------------------------------
// | Copyright (c) 2015~2020 http://www.buwangyun.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Gitee ( https://gitee.com/buwangyun/bwsaas )
// +----------------------------------------------------------------------
// | Author: buwangyun <hnlg666@163.com>
// +----------------------------------------------------------------------
// | Date: 2020-9-28 10:55:00
// +----------------------------------------------------------------------

namespace app\manage\controller;

use buwang\base\AdminBaseController;
use buwang\traits\JwtTrait;
use app\manage\model\AuthNode;
use app\manage\model\AuthGroupNode;
use app\common\model\Miniapp;
use  app\manage\model\admin\Plugin;
use think\facade\Cache;
use think\facade\Db;

class Node extends AdminBaseController
{
    use JwtTrait;

    /**
     * 查看
     * @menu true
     */
    public function index()
    {
        if (request()->isPost() || request()->isAjax()) {
            //适配老系统参数
            $pid = request()->get('pid');
            $keywords = $this->request->param('keywords', '');
            $where = [];
            if (isset($pid)) {
                $where[] = ['pid', '=', $pid];
            }else{
                $where[] = ['pid', '=', 0];
            }
            if ($keywords !== '') {
                $where[] = [
                    'menu_path',
                    'like',
                    "%${keywords}%",
                ];
            }
            $list = AuthNode::where('scopes', 'admin')->where($where)->order('sort desc, id desc')->select()->toArray();
            $count = AuthNode::where('scopes', 'admin')->where($where)->count();
            if (request()->param('return_type') == "old_json") {
                $list = array_merge(AuthNode::tree($list, 'title', 'id'));
                return json([
                    'code' => 0,
                    'msg' => '查询成功',
                    'count' => $count,
                    'data' => $list,
                ]);
            }
            return $this->success('success', ['total' => $count, 'list' => $list]);
        } else {
            return view();
        }
    }

    /**
     * 查看
     * @menu true
     */
    public function memberIndex()
    {
        if (request()->isPost() || request()->isAjax()) {
            //适配老系统参数
            $pid = request()->get('pid');
            $keywords = $this->request->param('keywords', '');
            $where = [];
            if (isset($pid)) {
                $where[] = ['pid', '=', $pid];
            }else{
                $where[] = ['pid', '=', 0];
            }
            if ($keywords !== '') {
                $where[] = [
                    'menu_path',
                    'like',
                    "%${keywords}%",
                ];
            }
            $list = Db::name('auth_node')->where('scopes', 'member')->where($where)->order('sort desc, id desc')->select()->toArray();
            $count = sizeof($list);
            if (request()->param('return_type') == "old_json") {
                $list = array_merge(AuthNode::tree($list, 'title', 'id'));
                return json([
                    'code' => 0,
                    'msg' => '查询成功',
                    'count' => $count,
                    'data' => $list,
                ]);
            }
            return $this->success('success', ['total' => $count, 'list' => $list]);
        } else {
            $this->error('request method not allowed');
        }
    }

    /**
     * 编辑节点
     * @return \think\Response
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function edit()
    {
        if ($this->request->isPost()) {
            $param = $this->request->post();
            //父级不能是自己
            if (isset($param['pid'])) {
                if ($param['pid'] == $param['id']) {
                    return $this->error('父ID不能是自己');
                }
            }
            $param['auth_name'] = AuthNode::getAuthName($param);
            //判断是否存在唯一标识
            if ($param['pid']) {
                //查询上级节点，
                $pAuthNode = AuthNode::find($param['pid']);
                //TODO:存在上级并且上级是插件中心才可以选则其他type
                if ($pAuthNode && !in_array($pAuthNode['auth_name'], ['manage_admin_plugin_core_index', 'manage_member_plugin_core_index'])) {
                    //比对是否和上级节点一致
                    if ($pAuthNode['app_name'] != $param['app_name'] || $pAuthNode['type'] != $param['type']) return $this->error('节点类型必须跟父节点一致');
                }
            }
            $result = AuthNode::update($param);
            //编辑中间表
            $AuthGroupNodes = AuthGroupNode::where('node_id', $param['id'])->select()->toArray();
            if ($AuthGroupNodes) {
                $AuthGroup_data = array();
                foreach ($AuthGroupNodes as $AuthGroupNode) {
                    $GroupNode = array();
                    $GroupNode ['id'] = $AuthGroupNode['id'];
                    if (isset($param['type'])) {
                        $GroupNode['type'] = $param['type'];
                    }
                    if (isset($param['name'])) {
                        $GroupNode['node_name'] = $param['name'];
                    }
                    if (isset($param['auth_name'])) {
                        $GroupNode['auth_name'] = $param['auth_name'];
                    }
                    $AuthGroup_data[] = $GroupNode;
                }
                $AuthGroupNode = new AuthGroupNode;
                $AuthGroupNode->saveAll($AuthGroup_data);
            }

            if ($result) {
                return $this->success('操作成功');
            } else {
                return $this->error('操作失败');
            }
        }
        $id = $this->request->get('id');
        $data = AuthNode::where('id', $id)->find();
//        $list = AuthNode::where('scopes', 'admin')->select()->toArray();
//        $list = AuthNode::tree($list, 'title', 'id');
        $miniapp = Miniapp::select()->toArray();
        $plugin = Plugin::select()->toArray();
        if ($this->request->isAjax()) {
            return $this->success('success', ['data' => $data, 'pid' => $this->request->get('pid'), 'miniapp' => $miniapp, 'plugin' => $plugin]);
        } else {
            return view('form', ['data' => $data, 'pid' => $data['pid'], 'miniapp' => $miniapp, 'plugin' => $plugin])->filter(function ($content) {
                return str_replace("&amp;", '&', $content);
            });
        }

    }


    /**
     * 编辑节点
     * @return \think\Response
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function editMember()
    {
        if ($this->request->isPost()) {
            $param = $this->request->post();
            //父级不能是自己
            if (isset($param['pid'])) {
                if ($param['pid'] == $param['id']) {
                    return $this->error('父ID不能是自己');
                }
            }
            $param['auth_name'] = AuthNode::getAuthName($param);
            if ($param['type'] == 'app_plugin') {
                $param['type'] = $param['type'] . '_' . $param['app_name'];
                $param['app_name'] = $param['plugin_name'];
            }

            //判断是否存在唯一标识
            if ($param['pid']) {
                //查询上级节点，
                $pAuthNode = AuthNode::find($param['pid']);
                //TODO:存在上级并且上级是插件中心才可以选则其他type
                if ($pAuthNode && !in_array($pAuthNode['auth_name'], ['manage_admin_plugin_core_index', 'manage_member_plugin_core_index'])) {
                    //比对是否和上级节点一致
                    if ($pAuthNode['app_name'] != $param['app_name'] || $pAuthNode['type'] != $param['type']) return $this->error('节点类型必须跟父节点一致');
                }
            }
            $result = AuthNode::update($param);
            //编辑中间表
            $AuthGroupNodes = AuthGroupNode::where('node_id', $param['id'])->select()->toArray();
            if ($AuthGroupNodes) {
                $AuthGroup_data = array();
                foreach ($AuthGroupNodes as $AuthGroupNode) {
                    $GroupNode = array();
                    $GroupNode ['id'] = $AuthGroupNode['id'];
                    if (isset($param['type'])) {
                        $GroupNode['type'] = $param['type'];
                    }
                    if (isset($param['name'])) {
                        $GroupNode['node_name'] = $param['name'];
                    }
                    if (isset($param['auth_name'])) {
                        $GroupNode['auth_name'] = $param['auth_name'];
                    }
                    $AuthGroup_data[] = $GroupNode;
                }
                $AuthGroupNode = new AuthGroupNode;
                $AuthGroupNode->saveAll($AuthGroup_data);
            }

            if ($result) {
                return $this->success('操作成功');
            } else {
                return $this->error('操作失败');
            }
        }
        $id = $this->request->get('id');
        $data = AuthNode::where('id', $id)->find();
        $list = AuthNode::where('scopes', 'member')->select()->toArray();
        $list = AuthNode::tree($list, 'title', 'id');
        //如果是插件类型则
        if (!in_array($data['type'], ['app', 'system'])) $data['plugin_title'] = $data['app_name'];
        $type_i = strpos($data['type'], 'app_plugin');
        if ($type_i !== false) {
            $data['app_name'] = str_replace("app_plugin_", "", $data['type']);
            $data['type'] = 'app_plugin';
        }
        $miniapp = Miniapp::select()->toArray();
        $plugin = Plugin::select()->toArray();
        return view('form_member', ['data' => $data, 'list' => $list, 'pid' => $data['pid'], 'miniapp' => $miniapp, 'plugin' => $plugin])->filter(function ($content) {
            return str_replace("&amp;", '&', $content);
        });
    }


    /**
     * 添加节点
     * @return \think\Response
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function add()
    {
        $param = $this->request->param();
        if ($this->request->isPost()) {
            $param['auth_name'] = AuthNode::getAuthName($param);
            //判断是否存在唯一标识
            if ($param['pid']) {
                //查询上级节点，
                $pAuthNode = AuthNode::find($param['pid']);
                //TODO:存在上级并且上级是插件中心才可以选则其他type
                if ($pAuthNode && !in_array($pAuthNode['auth_name'], ['manage_admin_plugin_core_index', 'manage_member_plugin_core_index'])) {
                    //比对是否和上级节点一致
                    if ($pAuthNode['app_name'] != $param['app_name'] || $pAuthNode['type'] != $param['type']) return $this->error('节点类型必须跟父节点一致');
                }
            }
            $result = AuthNode::create($param);
            if ($result) {
                return $this->success('操作成功');
            } else {
                return $this->error('操作失败');
            }
        } else {//get请求
            $miniapp = Miniapp::select()->toArray();
            $plugin = Plugin::select()->toArray();
        }

        if ($this->request->isAjax()) {
            return $this->success('success', ['pid' => $this->request->get('pid'), 'miniapp' => $miniapp, 'plugin' => $plugin]);
        } else {
            return view('form', ['pid' => $this->request->get('pid'), 'miniapp' => $miniapp, 'plugin' => $plugin])->filter(function ($content) {
                return str_replace("&amp;", '&', $content);
            });
        }
    }

    /**
     * 添加节点
     * @return \think\Response
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function addMember()
    {
        if ($this->request->isPost()) {
            $param = $this->request->post();
            $param['auth_name'] = AuthNode::getAuthName($param);
            if ($param['type'] == 'app_plugin') {
                $param['type'] = $param['type'] . '_' . $param['app_name'];
                $param['app_name'] = $param['plugin_name'];
            }

            //判断是否存在唯一标识
            //$count = AuthNode::where('auth_name', $param['auth_name'])->count();
            if ($param['pid']) {
                //查询上级节点，
                $pAuthNode = AuthNode::find($param['pid']);
                //TODO:存在上级并且上级是插件中心才可以选则其他type
                if ($pAuthNode && !in_array($pAuthNode['auth_name'], ['manage_admin_plugin_core_index', 'manage_member_plugin_core_index'])) {
                    //比对是否和上级节点一致
                    if ($pAuthNode['app_name'] != $param['app_name'] || $pAuthNode['type'] != $param['type']) return $this->error('节点类型必须跟父节点一致');
                }
            }
            $param['scopes'] = 'member';
            $result = AuthNode::create($param);
            if ($result) {
                return $this->success('操作成功');
            } else {
                return $this->error('操作失败');
            }
        }
        $list = AuthNode::where('scopes', 'member')->select()->toArray();
        $list = AuthNode::tree($list, 'title', 'id');
        $miniapp = Miniapp::select()->toArray();
        $plugin = Plugin::select()->toArray();
        return view('form_member', ['list' => $list, 'pid' => $this->request->get('pid'), 'miniapp' => $miniapp, 'plugin' => $plugin])->filter(function ($content) {
            return str_replace("&amp;", '&', $content);
        });
    }

    /**
     * 删除节点
     */
    public function delete($ids = 0)
    {
        if (request()->isPost()) {
            if (!$ids) return $this->error('参数有误');
            $list = AuthNode::where('id', 'in', $ids)->select();
            if (!$list) return $this->error('记录不存在');
            try {
                //$data = array();
                foreach ($list as $item) {
                    $child_count = AuthNode::where('pid', $item['id'])->count();
                    if ($child_count) return $this->error('请先删除子节点');
                    AuthNode::destroy($item['id']);
                    //删除中间表
                    $ids = AuthGroupNode::where('node_id', $item['id'])->column('id');
                    if ($ids) {
                        AuthGroupNode::destroy($ids);
                    }
                }
            } catch (\Exception $e) {
                return $this->error('删除失败', ['errorMsg' => $e->getMessage()]);
            }
            return $this->success('删除成功');
        }
        return $this->error('请求方法不对');
    }

    /**
     * 得到商品分类
     */
    public function getNodeTree()
    {
        $topAdminRoleId = config('auth.super_admin_role_id');//超级管理员角色
        $pid = $this->request->param('pid') ?: 0;//初始化商品分类
        $checked_ids = $this->request->param('checked_ids') ?: [];//初始化商品分类
        $disabled = $this->request->param('disabled') !== null ? $this->request->param('disabled') : true;//节点禁选
        $is_child = $this->request->param('is_child') ?: false;//是否只初始选中子节点
        $viewMode          = $this->request->param('viewMode') ? : FALSE; //是否为只读模式.
        $returnCheckedPids = $this->request->param('returnCheckedPids', FALSE); // 是否返回选择id的父id.
        if ($disabled === 'false') $disabled = false;
        if ($disabled === 'true') $disabled = true;
        if (!$pid || $pid == $topAdminRoleId) {
            $tree = AuthNode::getTree([['scopes', '=', 'admin']], 0, $checked_ids, $disabled, $is_child,$viewMode);

        } else {
            //得到父角色权限
            $NodeIds = AuthGroupNode::where('group_id', 'in', (string)$pid)->column('node_id');
            $tree = AuthNode::getTree([['id', 'in', $NodeIds], ['scopes', '=', 'admin']], 0, $checked_ids, $disabled, $is_child,$viewMode);

        }

        if ($returnCheckedPids && is_numeric($checked_ids)) {
            return $this->success('ok', [
                'tree'           => $tree,
                'allCheckedPids' => AuthNode::getAllPids($checked_ids, [['scopes', '=', 'admin']]),
            ]);
        }

        if (request()->param('return_type') == "old_json") {
            return json($tree);
        }
        return $this->success('success', $tree);
    }

    /**
     * 得到租户节点
     */
    public function getMemberNodeTree()
    {
        $pid = $this->request->param('pid') ?: 0;//初始化商品分类
        $checked_ids = $this->request->param('checked_ids') ?: [];//初始化商品分类
        $disabled = $this->request->param('disabled') !== null ? $this->request->param('disabled') : true;//节点禁选
        $is_child = $this->request->param('is_child') ?: false;//是否只初始选中子节点
        $type = $this->request->param('type') ?: '';//角色类型
        $app_name = $this->request->param('app_name') ?: '';//角色标识
        $scopes = $this->request->param('scopes/s') ?: 'member';//角色标识
        $viewMode          = $this->request->param('viewMode', FALSE); // 是否为只读模式.
        $returnCheckedPids = $this->request->param('returnCheckedPids', FALSE); // 是否返回选择id的父id.
        if ($disabled === 'false') $disabled = false;
        if ($disabled === 'true') $disabled = true;
        if ($type) {
            $base_ids = AuthNode::where('scopes', $scopes)->where('type', 'like', '%' . $type . '%')->where('app_name', $app_name)->column('id');
            if (!$pid) {
                $tree = AuthNode::getTree([['id', 'in', $base_ids], ['scopes', '=', $scopes]], 0, $checked_ids, $disabled, $is_child);

            } else {
                //得到父角色权限
                $NodeIds = AuthGroupNode::where('group_id', 'in', (string)$pid)->column('node_id');
                $NodeIds = array_unique(array_merge($NodeIds, $base_ids));//合并两个数组
                $tree = AuthNode::getTree([['id', 'in', $NodeIds], ['scopes', '=', $scopes]], 0, $checked_ids, $disabled, $is_child,$viewMode);

            }
        } else {
            if (!$pid) {
                $tree = AuthNode::getTree([['scopes', '=', $scopes]], 0, $checked_ids, $disabled, $is_child,$viewMode);

            } else {
                //得到父角色权限
                $NodeIds = AuthGroupNode::where('group_id', 'in', (string)$pid)->column('node_id');
                $tree = AuthNode::getTree([['id', 'in', $NodeIds], ['scopes', '=', $scopes]], 0, $checked_ids, $disabled, $is_child,$viewMode);

            }
        }

        if ($returnCheckedPids && is_numeric($checked_ids)) {
            return $this->success('ok', [
                'tree'           => $tree,
                'allCheckedPids' => AuthNode::getAllPids($checked_ids, [['scopes', '=', 'member']]),
            ]);
        }

        //返回API接口兼容旧版本
        if (request()->param('return_type') == "old_json") {
            return json($tree);
        }
        return $this->success('success', $tree);

    }

    /**
     * 排序
     */
    public function sort()
    {
        $param = $this->request->post();
        foreach ($param as $k => $v) {
            $v = empty($v) ? null : $v;
            if (!$v) $v = 0;
            AuthNode::where('id', $k)->save(['sort' => $v]);
        }
        return redirect('/manage/node/index');
    }

    /**
     * 更改菜单状态
     *
     * @return \think\Response
     */
    public function setShow()
    {
        if (request()->isAjax()) {
            $id = input('id/d');
            $data = AuthNode::find($id);
            if (!$data) $this->error('未找到节点！');
            $data['ismenu'] == 1 ? $is_menu = 0 : $is_menu = 1;
            AuthNode::update(['id' => $id, 'ismenu' => $is_menu]);
            return $this->success('success');

        }
    }

    /**
     * 更改开启状态
     *
     * @return \think\Response
     */
    public function setStatus()
    {
        if (request()->isAjax()) {
            $id = input('id/d');
            $data = AuthNode::find($id);
            if ($data['status'] === 0) {
                $data['status'] = 1;
            } elseif ($data['status'] === 1) {
                $data['status'] = 0;
            };
            $data->save();
            return $this->success('successful');
        }
        return $this->error('请求方法不对');
    }
}
